package model.object;

import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;

import model.general.Location;
import model.observer.Obsever;
import model.observer.Obseverable;

public class Hook extends ObjectAnimate implements Obseverable, Runnable {
	private List<Obsever> listObserver = new ArrayList<Obsever>();
	private ObjectAnimate itemsCatched;
	private static Hook uniqueInstance;
	private Boat boat;
	private boolean isCatching = false;
	private boolean isMove = true;

	public static Hook getInstance() {
		if (uniqueInstance == null) {
			uniqueInstance = new Hook(0, 0, "hook.jpg");
		}
		return uniqueInstance;
	}

	private Hook(int x, int y, String srcImg) {
		super(x, y, srcImg);
	}

	/**
	 * thay doi toa do cua Hook khi ma Boat move
	 * 
	 * @param loc
	 */
	@Override
	public void updateLocation(Location loc) {
		this.location.setX(loc.getX());
	}

	public void catchItems(ObjectAnimate obj) {
		itemsCatched = obj;
		isCatching = true;
	}

	public void setBoat(Boat boat) {

		this.boat = boat;
	}

	@Override
	public void show(Graphics g) {
		// TODO Auto-generated method stub
		g.drawLine(location.getX() + width, location.getY(), location.getX()
				+ width, location.getY() + 10);
		g.fillRect(location.getX() + width, location.getY(), 5, 20);
		g.fillRect(location.getX() + width, location.getY() + 20, 10, 10);
	}

	@Override
	public void move() {
		// TODO Auto-generated method st
		while (isMove) {
			// neu chua bat duoc cai gi hoac chua out ra khoi man hinh thi
			// moveDown
			// khi di chuyen xuong thi notify cac fish
			if (!isCatching || !hasOutPanel()) {
				move.moveDown();
				notifyObsever();
			} else {
				// neu bat duoc gi do hoac ra khoi man hinh thi moveup
				move.moveUp();

				// neu bat duoc gi do thi setLocation cho no di chuyen theo hook
				if (isCatching) {
					itemsCatched.updateLocation(location);
				}
				// neu ve toi tau roi thi reset lai tat ca va isMove = false ko
				// cho di chuyen
				if (isArrivedBoat()) {
					itemsCatched.reset();
					isMove = false;
				}
			}
			try {
				Thread.sleep(10);
			} catch (Exception e) {
				// TODO: handle exception
			}
		}

	}

	public boolean isArrivedBoat() {
		Rectangle rectHook = this.getBounds();
		Rectangle rectBoat = boat.getBounds();
		if (rectHook.intersects(rectBoat)) {
			return true;
		}
		return false;
	}

	@Override
	public void updateObject() {

	}

	@Override
	public void addObsever(Obsever obsever) {
		listObserver.add(obsever);
	}

	@Override
	public void notifyObsever() {
		for (int i = 0; i < listObserver.size(); i++) {
			listObserver.get(i).update();
		}
	}

	@Override
	public void removeObsever(Obsever obsever) {
		listObserver.remove(obsever);

	}

	@Override
	public void reset() {
		// TODO Auto-generated method stub

	}

	@Override
	public boolean hasOutPanel() {
		int min = boat.location.getY() + this.width;
		int max = this.pnl.getY() + this.pnl.getHeight() - this.height;
		if ((location.getY() < min) || (location.getY() > max))
			return true;
		return false;
	}

	@Override
	public void run() {
		move();

	}

}
